package com.backend.securitiessystem.task;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.backend.securitiessystem.crawler.po.*;
import com.backend.securitiessystem.crawler.service.CrawlerProvider;
import com.backend.securitiessystem.dao.*;
import com.backend.securitiessystem.enums.AppHttpCodeEnum;
import com.backend.securitiessystem.exception.BaseException;
import com.backend.securitiessystem.pojo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import lombok.extern.slf4j.Slf4j;


/**
 * 定时爬虫任务
 *
 * @author tuyufeng
 * @date 2024/05/21
 */
@Component
@Slf4j
public class FileCleanTask {

    @Resource
    private INewShareDao newShareDao;

    @Resource
    private CrawlerProvider crawlerProvider;

    @Resource
    private IIndexDao indexDao;

    @Resource
    private IFlashDao flashDao;

    @Resource
    private IRiseFallDao riseFallDao;

    @Resource
    private ICapitalFlowDao capitalFlowDao;

    /**
     * 更新中国指数定时任务
     *
     * @author tuyufeng
     * @date 2024/05/21
     */
    @Scheduled(fixedDelayString  = "#{@taskConfig.chinaIndexTime}")
    @Transactional(rollbackFor = Exception.class)
    public void updateChinaIndexTimingTask() {

        // 调用爬虫接口获取信息
        List<CrawledChinaIndex> indexList = crawlerProvider.getCrawledChinaIndexList();

        if (indexList.isEmpty()) {
            log.error(AppHttpCodeEnum.CRAWLER_FAIL_INDEX.getMsg());
            throw new BaseException(AppHttpCodeEnum.CRAWLER_FAIL_INDEX);
        }

        // 更新数据
        for (CrawledChinaIndex index : indexList) {
            Index indexEntity = new Index();
            BigDecimal lastPrice = BigDecimal.valueOf(index.getLatestPrice());

            // 查询该板块是否存在
            LambdaQueryWrapper<Index> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Index::getName, index.getName());
            Index indexFromSql = indexDao.selectOne(lqw);

            // 指数不存在,新增
            if (Objects.isNull(indexFromSql)) {
                indexEntity.setLatestPrice(BigDecimal.valueOf(index.getLatestPrice()));
                indexDao.insert(indexEntity);
            } else { // 存在,修改指数数据
                LambdaUpdateWrapper<Index> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(Index::getName, index.getName());
                updateWrapper.set(Index::getLatestPrice, lastPrice);
                indexDao.update(indexEntity, updateWrapper);
            }
        }

        // 打印日志
        log.info(AppHttpCodeEnum.CRAWLER_SUCCESS_INDEX.getMsg());
    }

    /**
     * 更新新股定时任务
     *
     * @author tuyufeng
     * @date 2024/05/21
     */
    @Scheduled(fixedDelayString  = "#{@taskConfig.newShareTime}")
    @Transactional(rollbackFor = Exception.class)
    public void updateNewShareTimingTask() {

        // 调用爬虫接口获取信息
        List<CrawledNewShare> crawledNewShareList = crawlerProvider.getCrawledNewShareList();

        if (crawledNewShareList.isEmpty()) {
            log.error(AppHttpCodeEnum.CRAWLER_FAIL_NEW_SHARE.getMsg());
            throw new BaseException(AppHttpCodeEnum.CRAWLER_FAIL_NEW_SHARE);
        }

        for (CrawledNewShare newShare : crawledNewShareList) {
            // 查询该新股是否存在
            LambdaQueryWrapper<NewShare> lqw = new LambdaQueryWrapper<>();
            lqw.eq(NewShare::getName, newShare.getName());
            NewShare shareFromSql = newShareDao.selectOne(lqw);

            // 不存在,添加
            if (Objects.isNull(shareFromSql)) {
                NewShare newShareEntity = new NewShare();
                newShareEntity.setName(newShare.getName());
                newShareEntity.setListingDate(newShare.getDate());
                newShareDao.insert(newShareEntity);
            }
        }

        // 打印日志
        log.info(AppHttpCodeEnum.CRAWLER_SUCCESS_NEW_SHARE.getMsg());
    }

    /**
     * 更新快讯定时任务
     *
     * @author tuyufeng
     * @date 2024/05/21
     */
    @Scheduled(fixedDelayString  = "#{@taskConfig.flashTime}")
    @Transactional(rollbackFor = Exception.class)
    public void updateFlashTimingTask() {

        // 调用爬虫接口获取信息
        List<CrawledSecuritiesNews> newsList = crawlerProvider.getCrawledSecuritiesNewsList();

        if (newsList.isEmpty()) {
            log.error(AppHttpCodeEnum.CRAWLER_FAIL_FLASH.getMsg());
            throw new BaseException(AppHttpCodeEnum.CRAWLER_FAIL_FLASH);
        }

        for (CrawledSecuritiesNews news : newsList) {

            // 获取标题
            Pattern pattern = Pattern.compile("【(.*?)】");
            Matcher matcher = pattern.matcher(news.getTitle());
            String newTitle = "";
            if (matcher.find()) {
                newTitle = matcher.group();
            }

            if (newTitle.isEmpty()) {
                continue;
            }

            // 根据标题查询资讯是否存在
            LambdaQueryWrapper<Flash> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Flash::getTitle, newTitle);
            Flash flashFromSql = flashDao.selectOne(lqw);

            // 不存在,添加
            if (Objects.isNull(flashFromSql)) {
                Flash flashEntity = new Flash();
                flashEntity.setTitle(newTitle);
                flashEntity.setTime(news.getDate());
                flashEntity.setType(news.getType());
                flashDao.insert(flashEntity);
            }
        }

        // 打印日志
        log.info(AppHttpCodeEnum.CRAWLER_SUCCESS_FLASH.getMsg());
    }

    /**
     * 更新板块资金流跌涨幅定时任务
     *
     * @author tuyufeng
     * @date 2024/05/21
     */
    @Scheduled(fixedDelayString  = "#{@taskConfig.riseFallTime}")
    @Transactional(rollbackFor = Exception.class)
    public void updateRiseFallTimingTask() {

        // 调用爬虫接口获取信息
        List<CrawledRiseFall> riseFallList = crawlerProvider.getCrawledRiseFallList();

        if (riseFallList.isEmpty()) {
            log.error(AppHttpCodeEnum.CRAWLER_FAIL_RISE_FALL.getMsg());
            throw new BaseException(AppHttpCodeEnum.CRAWLER_FAIL_RISE_FALL);
        }

        for (CrawledRiseFall riseFall : riseFallList) {
            // 查询该板块是否存在
            LambdaQueryWrapper<RiseFall> lqw = new LambdaQueryWrapper<>();
            lqw.eq(RiseFall::getPlateName, riseFall.getPlateName());
            RiseFall riseFallFromSql = riseFallDao.selectOne(lqw);

            BigDecimal bigDecimal = BigDecimal.valueOf(riseFall.getRange());
            bigDecimal = bigDecimal.abs();
            RiseFall riseFallEntity = new RiseFall();
            // 不存在,添加
            if (Objects.isNull(riseFallFromSql)) {
                riseFallEntity.setPlateName(riseFall.getPlateName());
                riseFallEntity.setRanges(bigDecimal);
                riseFallEntity.setStatus(riseFall.getStatus());
                riseFallDao.insert(riseFallEntity);
            } else { // 存在,更新
                // 修改指数数据
                LambdaUpdateWrapper<RiseFall> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(RiseFall::getPlateName, riseFall.getPlateName());
                updateWrapper.set(RiseFall::getRanges, bigDecimal);
                updateWrapper.set(RiseFall::getStatus, riseFall.getStatus());
                riseFallDao.update(riseFallEntity, updateWrapper);
            }
        }

        // 打印日志
        log.info(AppHttpCodeEnum.CRAWLER_SUCCESS_RISE_FALL.getMsg());
    }

    /**
     * 更新港股通资金流计时任务
     *
     * @author tuyufeng
     * @date 2024/05/22
     */
    @Scheduled(fixedDelayString  = "#{@taskConfig.capitalFlowTime}")
    @Transactional(rollbackFor = Exception.class)
    public void updateCapitalFlowTimingTask() {

        // 调用爬虫接口获取信息
        List<CrawledCapitalFlow> crawledCapitalFlowList = crawlerProvider.getCrawledCapitalFlowList();

        if (crawledCapitalFlowList.isEmpty()) {
            log.error(AppHttpCodeEnum.CRAWLER_FAIL_CAPITA_FLOW.getMsg());
            throw new BaseException(AppHttpCodeEnum.CRAWLER_FAIL_CAPITA_FLOW);
        }

        for (CrawledCapitalFlow capitalFlow : crawledCapitalFlowList) {

            CapitalFlow capitalFlowEntity = new CapitalFlow();
            BigDecimal flow = BigDecimal.valueOf(capitalFlow.getFlow());
            BigDecimal limits = BigDecimal.valueOf(capitalFlow.getLimit());
            BigDecimal balance = BigDecimal.valueOf(capitalFlow.getBalance());

            // 查询该板块是否存在
            LambdaQueryWrapper<CapitalFlow> lqw = new LambdaQueryWrapper<>();
            lqw.eq(CapitalFlow::getFlowName, capitalFlow.getFlowName());
            CapitalFlow capitalFlowFromSql = capitalFlowDao.selectOne(lqw);

            // 不存在,新增记录
            if (Objects.isNull(capitalFlowFromSql)) {
                capitalFlowEntity.setFlowName(capitalFlow.getFlowName());
                capitalFlowEntity.setFlow(flow);
                capitalFlowEntity.setLimits(limits);
                capitalFlowEntity.setBalance(balance);
                capitalFlowDao.insert(capitalFlowEntity);
            } else { // 存在,更新记录
                LambdaUpdateWrapper<CapitalFlow> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(CapitalFlow::getFlowName, capitalFlow.getFlowName());
                updateWrapper.set(CapitalFlow::getFlow, flow);
                updateWrapper.set(CapitalFlow::getLimits, limits);
                updateWrapper.set(CapitalFlow::getBalance, balance);
                capitalFlowDao.update(capitalFlowEntity, updateWrapper);
            }

        }

        // 打印日志
        log.info(AppHttpCodeEnum.CRAWLER_SUCCESS_CAPITA_FLOW.getMsg());
    }

}
